package com.firefly.admin.monitor.jobclass;

import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.firefly.admin.common.constant.Constants;
import com.firefly.admin.common.properties.BackupsDatabaseProperties;
import com.firefly.admin.common.utils.DateUtil;
import com.firefly.admin.monitor.entity.FyMonitorJob;
import com.firefly.admin.monitor.vo.JobExecuteResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.PostConstruct;
import java.io.File;
import java.io.FileWriter;
import java.util.*;

@Component
@Slf4j
public class BackupsDatabaseJobService {

    private static final String TABLE_NAME_LIST_PREFIX = "Tables_in_";

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private BackupsDatabaseProperties backupsDatabaseProperties;

    public JobExecuteResult backupsDatabase(FyMonitorJob monitorJob) {
        log.info("#########BackupsDatabaseJobService backupsDatabase job start !");
        JobExecuteResult jobExecuteResult = new JobExecuteResult();
        try {
            jobExecuteResult.setExecuteResult(Constants.LastExecuteResult.SUCCESS);
            String showTablesSql = "SHOW TABLES FROM " + backupsDatabaseProperties.getDatabase();
            List<String> tableNamelist = jdbcTemplate.query(showTablesSql, (rs, rowNum) -> rs.getString(TABLE_NAME_LIST_PREFIX + backupsDatabaseProperties.getDatabase()));
            if (CollectionUtils.isEmpty(tableNamelist)) {
                return jobExecuteResult;
            }
            List<String> insertTables = backupsDatabaseProperties.getInsertTables();
            StringBuilder initSql = new StringBuilder();
            initSql.append("# init time ").append(DateFormatUtils.format(DateUtil.getNowDate(), "yyyy-MM-dd HH:mm:ss")).append(System.lineSeparator());
            for (String tableName : tableNamelist) {
                String showCreateTableSql = "SHOW CREATE TABLE " + tableName;
                String createTable = jdbcTemplate.query(showCreateTableSql, rs -> {
                    String createTableSql = "";
                    while (rs.next()) {
                        createTableSql = rs.getString(2);
                    }
                    return createTableSql + StringPool.SEMICOLON + System.lineSeparator() + System.lineSeparator();
                });
                initSql.append(createTable);
                if (!CollectionUtils.isEmpty(insertTables) && insertTables.contains(tableName)) {
                    List<Map<String, Object>> list = jdbcTemplate.queryForList("SELECT * FROM " + tableName);
                    for (Map<String, Object> columnMap : list) {
                        StringBuilder insertColumnName = new StringBuilder();
                        StringBuilder insertColumnValue = new StringBuilder();
                        for (String columnName : columnMap.keySet()) {
                            Object obj = columnMap.get(columnName);
                            if (obj != null) {
                                insertColumnName.append(columnName).append(StringPool.COMMA);
                                insertColumnValue.append(StringPool.SINGLE_QUOTE).append(columnMap.get(columnName)).append(StringPool.SINGLE_QUOTE).append(StringPool.COMMA);
                            }
                        }
                        initSql.append("INSERT INTO ").append(tableName).append(" ( ").append(insertColumnName.substring(0, insertColumnName.length() - 1)).append(") values (").append(insertColumnValue.substring(0, insertColumnValue.length() - 1)).append(")" + StringPool.SEMICOLON).append(System.lineSeparator());
                    }
                    initSql.append(System.lineSeparator());
                }
            }
            File folder = new File(backupsDatabaseProperties.getFilePath());
            File[] files = folder.listFiles();
            if (files != null && files.length > 0) {
                //只保留三天文件
                Date nowDate = DateUtil.getNowDate();
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(nowDate);
                List<String> fileNameList = new ArrayList<>();
                for (int i = 0; i < 2; i++) {
                    calendar.add(Calendar.DAY_OF_MONTH, -1);
                    String fileNameTime = DateFormatUtils.format(calendar.getTime(), "yyyyMMdd");
                    fileNameList.add("init-" + fileNameTime + ".sql");
                }
                for (File file : files) {
                    String name = file.getName();
                    if (fileNameList.contains(name)) {
                        continue;
                    }
                    boolean delete = file.delete();
                    if (delete) {
                        log.info("BackupsDatabaseJobService delete [deleteFileName] success!! ");
                    }
                }
            }
            String addFileName = backupsDatabaseProperties.getFilePath() + "\\init-" + DateFormatUtils.format(DateUtil.getNowDate(), "yyyyMMdd") + ".sql";
            FileWriter writer = new FileWriter(addFileName);
            writer.write(initSql.toString());
            writer.close();
        } catch (Exception e) {
            e.printStackTrace();
            jobExecuteResult.setExecuteResult(Constants.LastExecuteResult.FAIL);
            jobExecuteResult.setErrorMsg(e.getMessage());
        }
        log.info("#########BackupsDatabaseJobService backupsDatabase job end !");
        return jobExecuteResult;
    }

    @PostConstruct
    public void test() {
        backupsDatabase(null);
    }
}
